package com.jmlong.config;

import com.auth0.jwt.interfaces.Claim;
import com.jmlong.domain.User;
import com.jmlong.service.UserService;
import com.jmlong.utils.JwtUtil;
import com.jmlong.utils.Result;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.Map;

@Slf4j
@WebFilter(filterName = "JwtFilter", urlPatterns = "/secure/*")
@Component
public class JwtFilter implements Filter {

    @Autowired
    UserService userService;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        final HttpServletRequest request = (HttpServletRequest) servletRequest;
        final HttpServletResponse response = (HttpServletResponse) servletResponse;

        response.setHeader("Access-Control-Allow-Origin",request.getHeader("Origin"));
        response.setHeader("Access-Control-Allow-Methods","*");
        response.setHeader("Access-Control-Allow-Credentials","true");
        response.setHeader("Access-Control-Allow-Headers","Authorization,Origin,X-Requested-With,Content-Type,Accept,Access-Token,token");

        response.setCharacterEncoding("UTF-8");

        //获取 header里的token
        final String token = request.getHeader("Authorization");

        // 放行登录接口
        if ("/user/login".equals(request.getRequestURI())) {
            response.setStatus(HttpServletResponse.SC_OK);
            filterChain.doFilter(request, response);
            return;
        }
        //放行注册接口
        if ("/user/register".equals(request.getRequestURI())) {
            response.setStatus(HttpServletResponse.SC_OK);
            filterChain.doFilter(request, response);
            return;
        }
        //放行查询所有商品接口
        if ("/commodity/getCommodityList".equals(request.getRequestURI())) {
            response.setStatus(HttpServletResponse.SC_OK);
            filterChain.doFilter(request, response);
            return;
        }
        //放行获取商品种类接口
        if ("/commodity/getCommodityType".equals(request.getRequestURI())) {
            response.setStatus(HttpServletResponse.SC_OK);
            filterChain.doFilter(request, response);
            return;
        }
        //放行搜索商品接口
        if ("/commodity/searchCommodity".equals(request.getRequestURI())) {
            response.setStatus(HttpServletResponse.SC_OK);
            filterChain.doFilter(request, response);
            return;
        }
        //放行OPTIONS方法
        if ("OPTIONS".equals(request.getRequestURI())) {
            response.setStatus(HttpServletResponse.SC_OK);
            filterChain.doFilter(request, response);
        }
        //放行静态资源访问
        if(request.getRequestURI().contains("img")){
//            log.info("静态资源请求，已放行....");
            response.setStatus(HttpServletResponse.SC_OK);
            filterChain.doFilter(request, response);
        }
        // Except OPTIONS, other request should be checked by JWT
        else {
            if (token == null) {
                Result result = new Result();
                result.setCode(400);
                result.setMsg("您还未登录，请先登陆！");
                JSONObject obj = JSONObject.fromObject(result);
                response.getWriter().write(obj.toString());
                return;
            }
//            log.info(token);
            // 验证token
            Map<String, Claim> userData;
            try{
                userData = JwtUtil.verifyToken(token);
            }catch (Exception e){
                log.info("token已过期");
                response.setHeader("Content-Type","application/json;charset=UTF-8");
                Result result = new Result();
                result.setCode(410);
                result.setMsg("您的登录信息已过期！请重新登陆！");
                JSONObject object = JSONObject.fromObject(result);
                log.info(object.toString());
                response.getWriter().write(object.toString());
                return;
            }
            if (userData == null) {
                response.setHeader("Content-Type","application/json;charset=UTF-8");
                Result result = new Result();
                result.setCode(400);
                result.setMsg("您的参数信息非法！");
                JSONObject obj = JSONObject.fromObject(result);
                response.getWriter().write(obj.toString());
                return;
            }
            String name = userData.get("name").asString();
            String loginName = userData.get("loginName").asString();
            User user = userService.checkToken(name, loginName); //检查token中带有的参数是否存在于数据库中

            if (user!=null){

                Date exp = userData.get("exp").asDate();   //token过期时间
                Date nowDate = new Date();

                long tempDate = (((exp.getTime()-nowDate.getTime()) / 1000) / 60);

                //过期时间小于十分钟时生成新的token,token已过期时直接返回
                if (tempDate<10 && tempDate>0){
                    String newToken = JwtUtil.createToken(user);
                    log.info("新的token为："+newToken);
                    response.setHeader("Access-Control-Expose-Headers","Authorization");
                    response.setHeader("Authorization",newToken);
                }else if(tempDate<0){
                    Result result = new Result();
                    result.setMsg("token已过期");
                    JSONObject object = JSONObject.fromObject(result);
                    log.info(object.toString());
                    response.getWriter().write(object.toString());
                    return;
                }
            }else {
                response.setHeader("Content-Type","application/json;charset=UTF-8");
                Result result = new Result();
                result.setMsg("您的登录信息不合法 请重新登录！");
                response.getWriter().write(JSONObject.fromObject(result).toString());
                return;
            }

            //拦截器 拿到用户信息，放到request中
//            request.setAttribute("id", id);
            request.setAttribute("name", name);
            request.setAttribute("loginName", loginName);
//            response.setHeader("Authorization",token);
            filterChain.doFilter(servletRequest, servletResponse);
        }
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}
